package com.yilin.tms.order.service.owner.impl;

import com.yilin.commons.exception.BusinessException;
import com.yilin.commons.util.ArrayUtil;
import com.yilin.commons.util.StringUtil;
import com.yilin.tms.core.application.AppUtil;
import com.yilin.tms.core.application.ReturnData;
import com.yilin.tms.core.commons.utils.ParamUtil;
import com.yilin.tms.core.entity.order.goods.GoodsOrder;
import com.yilin.tms.core.entity.order.payment.OrderPaymentCost;
import com.yilin.tms.core.entity.order.rob.RobOrder;
import com.yilin.tms.core.entity.system.param.CommTruckType;
import com.yilin.tms.core.entity.truck.TruckVehicle;
import com.yilin.tms.core.entity.user.UserType;
import com.yilin.tms.core.entity.user.account.Account;
import com.yilin.tms.core.entity.user.organize.MemberType;
import com.yilin.tms.order.service.owner.IGoodsOwnerService;
import com.yilin.tms.order.service.order.IRobService;
import com.yilin.tms.order.service.payment.IOrderPaymentCostService;
import com.yilin.tms.core.remote.ISystemRemote;
import com.yilin.tms.core.remote.IUserRemote;
import com.yilin.tms.core.remote.IVehicleRemote;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import javax.annotation.Resource;
import java.util.Arrays;
import java.util.Comparator;
import java.util.List;

/**
 * 货单前台操作标识
 *
 * @author zhangjinyuan
 * @date 2022/10/29
 */
@Service
@Transactional(rollbackFor = Exception.class)
public class GoodsOwnerService implements IGoodsOwnerService {

    @Resource
    IRobService robService;
    @Resource
    IOrderPaymentCostService paymentCostService;

    @Resource
    IUserRemote userRemote;
    @Resource
    IVehicleRemote vehicleRemote;
    @Resource
    ISystemRemote systemRemote;

    /**
     * 获取前台操作标识
     */
    @Override
    public void getCanOperationMark(Account loginUser, GoodsOrder goodsOrder,OrderPaymentCost goodsPayment) {
        //是否我的货源
        goodsOrder.setOwner(goodsOrder.getShipperAccountId().equals(loginUser.getId()));
        if (loginUser.getUserType() == UserType.shipperUser) {
            //是否已经支付
            goodsOrder.setShipperPay(goodsOrder.getOwner() && checkShipperPay(goodsPayment));
            //是否可以支付
            goodsOrder.setShipperCanPay(goodsOrder.getOwner() && checkShipperCanPay(goodsOrder));
            //是否能上线货源
            goodsOrder.setShipperCanRelease(goodsOrder.getOwner() && checkShipperCanRelease(goodsOrder));
            //是否能预约上线货源
            goodsOrder.setShipperCanReserve(goodsOrder.getOwner() && checkShipperCanReserve(goodsOrder));
            //是否能分配
            goodsOrder.setShipperCanAssign(goodsOrder.getOwner() && checkShipperCanAssign(goodsOrder));
            //是否能下线
            goodsOrder.setShipperCanOffLine(goodsOrder.getOwner() && checkShipperCanOffLine(goodsOrder));
            //是否能编辑
            goodsOrder.setShipperCanEdit(goodsOrder.getOwner() && checkShipperCanEdit(goodsOrder));
            //是否有可审核的抢单
            goodsOrder.setShipperCanRobOrder(goodsOrder.getOwner() && checkShipperCanRobOrder(goodsOrder));
            //是否能作废
            goodsOrder.setShipperCanScrap(goodsOrder.getOwner() && checkShipperCanScrap(goodsOrder));
        }
        if (loginUser.getUserType() == UserType.truckerUser) {
            ReturnData<String> returnData = truckerCanRob(loginUser, goodsOrder);
            //是否可申请抢单
            goodsOrder.setTruckerCanRob(returnData.isSuccess());
            //不能抢单的原因
            goodsOrder.setNotRobReason(returnData.getMsg());
            //匹配的车型有哪些
            goodsOrder.setMatchTruckTypeNames(returnData.getData());
        }
        //操作提示
        goodsOrder.setOptTip(getOptTip(loginUser, goodsOrder));
    }

    /**
     * 隐藏货源敏感信息
     */
    @Override
    public void goodsPrivateData(GoodsOrder goodsOrder) {
        //隐藏货主名
        if (StringUtil.isNotEmpty(goodsOrder.getShipperOrganizeName())) {
            goodsOrder.setShipperOrganizeName(StringUtil.privateName(goodsOrder.getShipperOrganizeName()));
        }
        //隐藏货主名
        if (StringUtil.isNotEmpty(goodsOrder.getShipperAccountName())) {
            goodsOrder.setShipperAccountName(StringUtil.privateName(goodsOrder.getShipperAccountName()));
        }
        //货主电话
        if (StringUtil.isNotEmpty(goodsOrder.getShipperAccountPhone())) {
            goodsOrder.setShipperAccountPhone(StringUtil.privatePhone(goodsOrder.getShipperAccountPhone()));
        }
    }

    /**
     * 检查货源发布配置
     * 能不能发布
     */
    @Override
    public void checkGoodsRelease(GoodsOrder goodsOrder) {
        MemberType memberType = ParamUtil.isSuccess(userRemote.getMyMemberTypeConfig(goodsOrder.getShipperOrganizeId()));
//        //检查计价模式
//        if (goodsOrder.getPriceMode() == GoodsOrder.PriceMode.wholePrice && !existenceMap.get(IncrementConstant.supportWholePricing)) {
//            throw new BusinessException("抱歉！您不被支持使用整车计价模式");
//        }
//        if (goodsOrder.getPriceMode() == GoodsOrder.PriceMode.unitPrice && !existenceMap.get(IncrementConstant.supportUnitPricing)) {
//            throw new BusinessException("抱歉！您不被支持使用单价计价模式");
//        }
//        if (goodsOrder.getPriceMode() == GoodsOrder.PriceMode.notPrice && !existenceMap.get(IncrementConstant.supportNotPricing)) {
//            throw new BusinessException("抱歉！您不被支持使用不计价模式");
//        }
//        //结算模式支持
//        if (goodsOrder.getSettlementType() == GoodsOrder.SettlementType.releasePricing && !existenceMap.get(IncrementConstant.supportPricingSettlement)) {
//            throw new BusinessException("抱歉！您不被支持使用一口价结算");
//        }
//        if (goodsOrder.getSettlementType() == GoodsOrder.SettlementType.assignWav && !existenceMap.get(IncrementConstant.supportAssignMeteSettlement)) {
//            throw new BusinessException("抱歉！您不被支持使用分配量结算");
//        }
//        if (goodsOrder.getSettlementType() == GoodsOrder.SettlementType.loadingWav && !existenceMap.get(IncrementConstant.supportLoadingMeteSettlement)) {
//            throw new BusinessException("抱歉！您不被支持使用装货量结算");
//        }
//        if (goodsOrder.getSettlementType() == GoodsOrder.SettlementType.deliverWav && !existenceMap.get(IncrementConstant.supportDeliverMeteSettlement)) {
//            throw new BusinessException("抱歉！您不被支持使用发货量结算");
//        }
//        if (goodsOrder.getSettlementType() == GoodsOrder.SettlementType.arriveWav && !existenceMap.get(IncrementConstant.supportArriveMeteSettlement)) {
//            throw new BusinessException("抱歉！您不被支持使用签收量结算");
//        }
//        if (goodsOrder.getSettlementType() == GoodsOrder.SettlementType.gatherTotal && !existenceMap.get(IncrementConstant.supportGatherTotalSettlement)) {
//            throw new BusinessException("抱歉！您不被支持使用汇总结算");
//        }
//        //账户支持
//        if (goodsOrder.getAutoDelivery() && !existenceMap.get(IncrementConstant.supportAutoDeliver)) {
//            throw new BusinessException("抱歉！您不被支持使用自动发货");
//        }
//        if (goodsOrder.getStartFence() && !existenceMap.get(IncrementConstant.supportElectronicFence)) {
//            throw new BusinessException("抱歉！您不被支持使用电子围栏");
//        }
        //关联检查
        GoodsOrder.SettlementType[] wholePricing = new GoodsOrder.SettlementType[]{GoodsOrder.SettlementType.releasePricing, GoodsOrder.SettlementType.gatherTotal};
        if (goodsOrder.getPriceMode() == GoodsOrder.PriceMode.wholePrice && !Arrays.asList(wholePricing).contains(goodsOrder.getSettlementType())) {
            throw new BusinessException("整单计价模式下不支持该结算类型");
        }
        if (goodsOrder.getPriceMode() == GoodsOrder.PriceMode.notPrice && goodsOrder.getSettlementType() != GoodsOrder.SettlementType.gatherTotal) {
            throw new BusinessException("汇总计价模式下仅支持汇总结算类型");
        }
        if (!goodsOrder.getMatching() && !goodsOrder.getIncludedTax()) {
            throw new BusinessException("非撮合业务（承运业务）必含税");
        }
        if (!goodsOrder.getNoBargain() && goodsOrder.getAutoAudit()) {
            throw new BusinessException("议价模式不能自动审核");
        }
    }


    /**
     * 操纵提示
     */
    private String getOptTip(Account loginUser, GoodsOrder goodsOrder) {
        if (loginUser.getUserType() == UserType.shipperUser) {
            if (goodsOrder.getShipperCanPay()) return "货源需要支付，请尽快付款";
            if (goodsOrder.getShipperCanRelease()) return "货源可以发布，发布后司机可抢单";
            if (!goodsOrder.getOwner()){
                goodsPrivateData(goodsOrder);
                return "正在浏览他人货源，如需发货帮助，请仔细阅读“帮助文档";
            }
            return goodsOrder.getGoodsStatus().shipperTip;
        }
        if (loginUser.getUserType() == UserType.truckerUser) {
            if (goodsOrder.getGoodsStatus() == GoodsOrder.GoodsStatus.release) {
                ReturnData<String> returnData = truckerCanRob(loginUser, goodsOrder);
                return returnData.getMsg();
            }
        }
        return "正在浏览中，登录货主/车主查看更多详情";
    }

    /**
     * 获取货源详情链接
     * 例：http://127.0.0.1:8082/logistics/goods/getgoodsOrderDetail.do?goodsOrderId=123
     */
    @Override
    public String getGoodsOrderDetailUrl(String goodsOrderId) {
        String zuulPath = AppUtil.getZuulPath();
        return zuulPath + "/order/goods/getPublicGoodsOrderDetail?goodsOrderId=" + goodsOrderId;
    }

    /**
     * 是否已经支付或无需支付
     */
    private Boolean checkShipperPay(OrderPaymentCost paymentCost) {
        if (paymentCost == null) return false;
        if (paymentCost.getPayStatus() == OrderPaymentCost.PayStatus.none) return true;
        return paymentCost.getPayStatus() == OrderPaymentCost.PayStatus.complete;
    }

    /**
     * 是否可以支付
     */
    private Boolean checkShipperCanPay(GoodsOrder goodsOrder) {
        if (goodsOrder.getGoodsStatus() != GoodsOrder.GoodsStatus.save) return false;
        return !goodsOrder.getShipperPay();
    }

    /**
     * 是否能上线货源
     */
    private Boolean checkShipperCanRelease(GoodsOrder goodsOrder) {
        if (goodsOrder.getGoodsStatus() != GoodsOrder.GoodsStatus.save) return false;
        return goodsOrder.getShipperPay();
    }

    /**
     * 是否能预约上线货源
     */
    private Boolean checkShipperCanReserve(GoodsOrder goodsOrder) {
        if (goodsOrder.getGoodsStatus() != GoodsOrder.GoodsStatus.save) return false;
        return goodsOrder.getShipperPay();
    }

    /**
     * 是否能分配
     */
    private Boolean checkShipperCanAssign(GoodsOrder goodsOrder) {
        if (goodsOrder.getGoodsStatus() != GoodsOrder.GoodsStatus.save) return false;
        return goodsOrder.getShipperPay();
    }

    /**
     * 是否能下线
     */
    private Boolean checkShipperCanOffLine(GoodsOrder goodsOrder) {
        //发布方可下线
        return goodsOrder.getGoodsStatus() == GoodsOrder.GoodsStatus.release;
    }

    /**
     * 是否能引用编辑发布
     */
    private Boolean checkShipperCanEdit(GoodsOrder goodsOrder) {
        if (goodsOrder.getGoodsStatus() == GoodsOrder.GoodsStatus.template) return true;
        return goodsOrder.getGoodsStatus() == GoodsOrder.GoodsStatus.scrap;
    }

    /**
     * 是否有可审核的抢单
     */
    private Boolean checkShipperCanRobOrder(GoodsOrder goodsOrder) {
        List<RobOrder> robOrders = robService.getWaitRobByGoodsOrderId(null, goodsOrder.getId());
        return robOrders.size() > 0;
    }

    /**
     * 是否能作废
     */
    private Boolean checkShipperCanScrap(GoodsOrder goodsOrder) {
        //作废时退款，模板也能作废
        return goodsOrder.getGoodsStatus() != GoodsOrder.GoodsStatus.scrap;
    }

    /**
     * 是否可申请抢单
     */
    private ReturnData<String> truckerCanRob(Account loginUser, GoodsOrder goodsOrder) {
        if (goodsOrder.getGoodsStatus() != GoodsOrder.GoodsStatus.release) return ReturnData.from(false,"货源未发布,不能抢单");
        if (loginUser.getUserType() != UserType.truckerUser) return ReturnData.from(false,"您不是车主用户，不能抢单");
        List<RobOrder> robOrders = robService.getWaitRobByGoodsOrderId(loginUser.getId(), goodsOrder.getId());
        if (robOrders.size() > 0) {
            goodsOrder.setRobOrderId(ArrayUtil.first(robOrders).getId());
            return ReturnData.from(false,"您已经存在未审核抢单，请先等待审核");
        }
        return robVehicleTypeMatching(loginUser.getOrganizeId(), goodsOrder);
    }

    /**
     * 车主所有车辆类型与货源需求类型匹配
     */
    @Override
    public ReturnData<String> robVehicleTypeMatching(String organizeId, GoodsOrder goodsOrder) {
        List<TruckVehicle> truckVehicleList = ParamUtil.isSuccess(vehicleRemote.getVehicleListByOrganizeId(organizeId));
        if (ArrayUtil.isEmpty(truckVehicleList)) return ReturnData.from(false,"您还没有添加车辆，请添加车辆后抢单","无");
        //货源不限车辆：所有存在车辆的用户均可以抢单
        if (StringUtil.isEmpty(goodsOrder.getTruckTypeIds())) return ReturnData.from(true,"货源不限车型，请尽快发起抢单","不限车型");
        List<TruckVehicle> unusedTruckVehicles = ArrayUtil.whereBy(truckVehicleList, obj -> obj.getTruckStatus() == TruckVehicle.TruckStatus.unused);
        if (unusedTruckVehicles.size()==0) return ReturnData.from(false,"您没有空闲中的车辆，请运输完成后再抢单","无");
        //获取货源最小匹配级别的车型，最小车型匹配，就可以抢单
        String[] shipperTruckTypeIds = goodsOrder.getTruckTypeIds().split(",");
        List<CommTruckType> truckTypeList = ParamUtil.isSuccess(systemRemote.getCommTruckTypeListByIds(shipperTruckTypeIds));
        truckTypeList.sort(Comparator.comparing(CommTruckType::getRobMatchRank));
        CommTruckType minType = ArrayUtil.first(truckTypeList);
        //获取所有匹配车型的车辆，所有大于最小匹配车型的车辆均可以抢单，返回所有匹配的车型名称
        List<TruckVehicle> matchTruckVehicleList = ArrayUtil.whereBy(truckVehicleList, obj -> obj.getCommTruckTypeMatchRank() >= minType.getRobMatchRank());
        if (matchTruckVehicleList.size()==0) return ReturnData.from(false,"您没有合适车型匹配货源，请查看货源车型要求","无");
        String matchTruckTypeNames = ArrayUtil.join(matchTruckVehicleList, ",", (obj, idx) -> obj.getCommTruckTypeName());
        return ReturnData.from(true,"您拥有货源匹配车型，请尽快发起抢单",matchTruckTypeNames);
    }

}